package cz.muni.fi.pa165.business.daoimpl;

import cz.muni.fi.pa165.business.dao.PickerDAO;
import cz.muni.fi.pa165.business.entity.Picker;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.stereotype.Repository;

/**
 *
 * @author Matej Cimbora
 */
@Repository
public class PickerDAOImpl implements PickerDAO {

    @PersistenceContext
    private EntityManager em;
    
    @Autowired
    private ShaPasswordEncoder sha;

    @Override
    public void createPicker(Picker picker) {

        if (picker == null) {
            throw new IllegalArgumentException("Argument can not be null");
        }

        if (picker.getId() != null) {
            throw new IllegalArgumentException("Picker's id has already been set");
        }

        if (em == null) {
            System.out.println("EM je rovny NULL");
        }

        Query q = em.createQuery("SELECT p FROM cz.muni.fi.pa165.business.entity.Picker p "
                + "WHERE p.nickName = :nickName");
        q.setParameter("nickName", picker.getNickName());

        if (!q.getResultList().isEmpty()) {
            throw new IllegalArgumentException("Picker with given nickname: " + picker.getNickName()
                    + " already exists!");
        }

        try {
            String digest = sha.encodePassword(picker.getPassword(),null);
            picker.setPassword(digest);
            em.persist(picker);
        } finally {
            em.close();
        }
    }

    @Override
    public void updatePicker(Picker picker) {

        if (picker == null) {
            throw new IllegalArgumentException("Argument can not be null");
        }

        try {
            Picker p = em.find(Picker.class, picker.getId());
            p.setFirstName(picker.getFirstName());
            p.setLastName(picker.getLastName());
            p.setPickerInfo(picker.getPickerInfo());
            String digest = sha.encodePassword(picker.getPassword(),null);
            p.setPassword(digest);
            p.setNickName(picker.getNickName());
            p.setUserRole(picker.getUserRole());
            em.merge(p);
        } finally {
            em.close();
        }
    }

    @Override
    public void deletePicker(Picker picker) {

        if (picker == null) {
            throw new IllegalArgumentException("Argument can not be null");
        }

        if (picker.getId() == null) {
            throw new IllegalArgumentException("Id can not be null in delete function, argument is not in database");
        }

        try {
            Picker p = em.find(Picker.class, picker.getId());
            em.remove(p);
        } finally {
            em.close();
        }
    }

    @Override
    public Picker getPicker(Long id) {

        if (id == null) {
            throw new IllegalArgumentException("Argument can not be null");
        }

        if (id.longValue() < 0) {
            throw new IllegalArgumentException("Id can not be negative");
        }

        try {
            return em.find(Picker.class, id);
        } finally {
            em.close();
        }
    }

    @Override
    public List<Picker> findAllPickers() {

        try {
            Query q = em.createQuery("SELECT p FROM cz.muni.fi.pa165.business.entity.Picker p");
            return q.getResultList();
        } catch (NoResultException ex) {
            return null;
        } finally {
            em.close();
        }
    }

    @Override
    public Picker findPickerByNickName(String nickName) {

        if (nickName == null || nickName.isEmpty()) {
            throw new IllegalArgumentException("Argument can not be null or empty");
        }

        try {
            Query q = em.createQuery("SELECT p FROM cz.muni.fi.pa165.business.entity.Picker p "
                    + "WHERE p.nickName = :nickName");
            q.setParameter("nickName", nickName);
            return (Picker) q.getSingleResult();
        } catch (NoResultException ex) {
            return null;
        } finally {
            em.close();
        }
    }

    @Override
    public List<Picker> findPickersByFirstName(String firstName) {

        if (firstName == null || firstName.isEmpty()) {
            throw new IllegalArgumentException("Argument cannot be null or empty");
        }

        try {
            Query q = em.createQuery("SELECT p FROM cz.muni.fi.pa165.business.entity.Picker p "
                    + "WHERE p.firstName = :firstName");
            q.setParameter("firstName", firstName);
            return q.getResultList();
        } catch (NoResultException ex) {
            return null;
        } finally {
            em.close();
        }
    }

    @Override
    public List<Picker> findPickersByLastName(String lastName) {

        if (lastName == null || lastName.isEmpty()) {
            throw new IllegalArgumentException("Last name cannot be null or empty");
        }

        try {
            Query q = em.createQuery("SELECT p FROM cz.muni.fi.pa165.business.entity.Picker p "
                    + "WHERE p.lastName = :lastName");
            q.setParameter("lastName", lastName);
            return q.getResultList();
        } catch (NoResultException ex) {
            return null;
        } finally {
            em.close();
        }
    }
}
